home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / sound / rukc1d.zip / RUCK_SRC.ZIP / X02M.C < prev    next >
C/C++ Source or Header  |  1994-02-27  |  7KB  |  212 lines

  1.  
  2. #include <dos.h>
  3. #include <conio.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <stdarg.h>
  7.  
  8. #include "ruckmidi.h"
  9.  
  10. /*
  11. X02M.c 27-Feb-94 chh
  12. remove C7-specific _ all over the place
  13. OutMsgMidi example
  14. */
  15.  
  16. /*
  17. The following structures are in ruckdac.h
  18. */
  19.  
  20. #pragma pack(1)  /* ALL Ruckus data structures must be byte-aligned */
  21.  
  22. extern struct MidiDataArea pascal MIDIDATA;
  23.  
  24. struct SysInfoMidiPack SIMP;
  25. struct InitMidiPack IMP;
  26. struct XitMidiPack XMP;
  27. struct LoadMidiPack LMP;
  28. struct SetMidiPack SMP;
  29. struct SetFMProPack SFMPP;
  30. struct PlaybackMidiPack PBMP;
  31. struct OutMsgMidiPack OMMP;
  32. struct DeallocMidiPack DMP;
  33.  
  34. #pragma pack()
  35.  
  36. int rez, rez2;      /* result status codes */
  37. char nums[9] = {7}; /* number buffer for _cgets()*/
  38. char filename[81];  /* pathname to load */
  39.  
  40.  
  41. int main()
  42. {
  43.  
  44.     int pc=0, sSize=0;
  45.     unsigned i=0;
  46.     unsigned pitchbend=0x2000;  /* mid-value of 0-8192 range */
  47.  
  48.     printf("\nX02M.C - RUCKUS-MIDI OutMsgMidi example. [930228]\n");
  49.  
  50.     /*
  51.     Initialize RUCKMIDI and device and register ExitMidi with _atexit
  52.     */
  53.  
  54.     IMP.Func = InitMidi;
  55.     IMP.DeviceID = 1;           /* OPL-2 percussive mode */
  56.     IMP.IOport = 0x388;
  57.     IMP.ChMask = 0x23F;
  58.     IMP.PercCh = 9;
  59.     IMP.Flags = 0;
  60.     rez = RUCKMIDI(&IMP);                 /* Initialize */
  61.     if (rez == 0) {
  62.  
  63.         XMP.Func = AtExitMidi;
  64.         rez2 = RUCKMIDI(&XMP);
  65.         if (rez2 != 0) {
  66.             printf("AtExitMidi failed, press Enter to continue");
  67.             getchar();
  68.         }
  69.  
  70.         /*
  71.         Increase SB Pro main and FM vol volumes to max
  72.         */
  73.  
  74.         SFMPP.Func = SetAllFMSBP;
  75.         SFMPP.IOport = 0x220;       /* if there it'll respond */
  76.         SFMPP.MasterVol = 0x0F0F;   /* if not, no problem */
  77.         SFMPP.Steer = 0;
  78.         SFMPP.FMvol = 0x0F0F;
  79.         rez2 = RUCKMIDI(&SFMPP);
  80.  
  81.  
  82.         /*
  83.         Set patch map to, oh, let's use GM
  84.         */
  85.  
  86.         SMP.Func = SetPatchMidi;
  87.         SMP.PatchMapID = 0;     /* actually, this is the GM is the default */
  88.         SMP.PatchMapPtr = NULL;
  89.         rez2 = RUCKMIDI(&SMP);
  90.  
  91.         do {
  92.             printf("\nProgram# to sound (0-127, -1 to end): ");
  93.         pc = atoi(cgets(nums));
  94.             if ((pc < 0) || (pc > 127))
  95.                 break;
  96.  
  97.             OMMP.Func = OutMsgMidi;
  98.             OMMP.Mstatus = 0xC0;    /* channel 0 program change */
  99.             OMMP.Mdata = pc;
  100.             rez2 = RUCKMIDI(&OMMP);
  101.  
  102.             printf("\n------------------------------------");
  103.             printf("\nChannel 0 is using program number: %i\n",pc);
  104.  
  105.             /*
  106.             In NoteOn Mdata is key number (0-127 MIDI, but OPL-2 key
  107.             numbers are valid from 12 to 107, see docs for more)
  108.             in the low byte. Key velocity (0-127) is in the high byte.
  109.             --velocity is essentially the volume desired.
  110.             */
  111.  
  112.             OMMP.Func = OutMsgMidi; /* really don't need to set it again */
  113.             OMMP.Mstatus = 0x90;    /* NoteOn, channel 0 */
  114.             OMMP.Mdata = 0x7F3C;    /* note=60 = 262Hz, max volume=7F */
  115.             rez2 = RUCKMIDI(&OMMP);
  116.  
  117.             printf("Playing a note with the NoteOn command\n");
  118.             printf("Press Enter to send NoteOff command...\n");
  119.             printf(" (NoteOn) ");
  120.             printf("Note: %u, Channel: %u, Volume: %u",
  121.                  (OMMP.Mdata & 0x7F),(OMMP.Mstatus & 0x0F),(OMMP.Mdata >>8));
  122.  
  123.             gets(filename);
  124.             printf(" (NoteOff)\n");
  125.  
  126.             /*
  127.             Note that sending a NoteOn (above) with velocity=0 has the same
  128.             effect as performing an explicit NoteOff--often in MIDI data
  129.             streams NoteOn with a velocity=0 is used rather than the specfic
  130.             NoteOff message--here the NoteOff message is used (with the
  131.             NoteOn method commented-out.
  132.             */
  133.  
  134.             OMMP.Func = OutMsgMidi;
  135.             OMMP.Mstatus = 0x80;    /* NoteOff, channel 0 */
  136.             OMMP.Mdata = 0;         /* any data will do */
  137.             rez2 = RUCKMIDI(&OMMP);
  138.  
  139.             /*
  140.             OMMP.Func = OutMsgMidi;
  141.             OMMP.Mstatus = 0x90;
  142.             OMMP.Mdata = 0x3C;
  143.             rez2 = RUCKMIDI(&OMMP);
  144.             */
  145.  
  146.             printf("\nPress Enter...");
  147.             gets(filename);
  148.  
  149.             /*
  150.             Do something a little more exciting than that.
  151.             See OutMsgMidi for more on MIDI channel messages in general.
  152.             */
  153.  
  154.             printf("Playing the same note but applying +/- pitchbend\n");
  155.  
  156.             OMMP.Func = OutMsgMidi;
  157.             OMMP.Mstatus = 0x90;    /* NoteOn, channel 0 */
  158.             OMMP.Mdata = 0x7F3C;    /* same note as above */
  159.             rez2 = RUCKMIDI(&OMMP);
  160.  
  161.             printf(" (NoteOn) ");
  162.             printf("Note: %u, Channel: %u, Volume: %u\n",
  163.                  (OMMP.Mdata & 0x7F),(OMMP.Mstatus & 0x0F),(OMMP.Mdata >>8));
  164.  
  165.             /*
  166.             Using just pitchbend this alters the frequency of the note being
  167.             played.
  168.             It's best to use a program that remains at the sustain level
  169.             until a NoteOff is sent--programs that have EG=1 will do so
  170.             (a high SL is also desired)(see OutMsgMidi for more).
  171.             */
  172.  
  173.             OMMP.Func = OutMsgMidi;
  174.             OMMP.Mstatus = 0xE0;    /* Pitchbend, channel 0 */
  175.  
  176.             sSize = 32;             /* CPU-speed dependent effect */
  177.  
  178.             for (i=0;i<10;i++) {
  179.                 for (pitchbend=0x2000;pitchbend > 0;pitchbend-=sSize) {
  180.                     OMMP.Mdata = pitchbend;
  181.                     rez2 = RUCKMIDI(&OMMP);
  182.                 }
  183.                 /* might want to put a check_key exit in here */
  184.                 for (pitchbend=0;pitchbend < 0x3FFF;pitchbend+=sSize) {
  185.                     OMMP.Mdata = pitchbend;
  186.                     rez2 = RUCKMIDI(&OMMP);
  187.                 }
  188.                 /* here too */
  189.                 for (pitchbend=0x3FFF;pitchbend > 0x2000;pitchbend-=sSize) {
  190.                     OMMP.Mdata = pitchbend;
  191.                     rez2 = RUCKMIDI(&OMMP);
  192.                 }
  193.             }
  194.  
  195.             OMMP.Func = OutMsgMidi;
  196.             OMMP.Mstatus = 0x80;        /* NoteOff, channel 0 */
  197.             OMMP.Mdata = 0;             /* any data */
  198.             rez2 = RUCKMIDI(&OMMP);
  199.             puts(" (NoteOff)");
  200.  
  201.         }
  202.         while (1);
  203.     }
  204.     else
  205.         printf("\nInitialization failed, %i\n",rez);
  206.  
  207. XMP.Func = ExitMidi;
  208. rez = RUCKMIDI(&XMP);
  209. return(rez);
  210.  
  211. }
  212.